<?php

/*****************************************************

  Copyright:	(c) 2008  SeaDesign Web Studio
        Web:	www.seadesign.ru
      Email: 	seadesign@gmail.com
  
*****************************************************/

class User
{
	function __construct($id)
	{
		$q = createQuery(
			"SELECT login, password, salt, name, email, lang, descr, registered, last_login, enabled
			FROM cf_users
			WHERE id=:id",
			array('id'=>$id)
		);
		$q->execute();
		if (!$q->fetch())
		{
			throw new Exception('Invalid user');
		}
		$this->id = (int)$id;
		$this->login = $q->at(0);
		$this->password = $q->at(1);
		$this->salt = $q->at(2);
		$this->name = $q->at(3);
		$this->email = $q->at(4);
		$this->lang = $q->at(5);
		$this->descr = $q->at(6);
		$this->registered = $q->at(7);
		$this->last_login = $q->at(8);
		$this->enabled = $q->at(9);
		$q->close();
	}
	
	public function name()
	{
		return $this->name;
	}

	public function loginName()
	{
		return $this->login;
	}
	
	public function id()
	{
		return $this->id;
	}

	public function email()
	{
		return $this->email;
	}
	
	public function isEnabled()
	{
		return (bool)$this->enabled==1;
	}
	
	public function setEmail($email)
	{
		execQuery("UPDATE cf_users SET email=:email WHERE id={$this->id}", array('email'=>$email));
		return $this;
	}
	
	public function logout()
	{
		$c = Cookie::retrieve('user');
		if ($c) {
			$c->delete();
		}
	}
	
	/**	@return user ID	or false */
	static public function findByLogin($login)
	{
		$q = createQuery(
			"SELECT id FROM cf_users WHERE login=:login",
			array('login'=>$login)
		);
		$q->execute();
		if (!$q->fetch())
		{
			return false;
		}
		return $q->at(0);
	}
	
	/**	@return user ID	or false */
	static public function findByEmail($email)
	{
		$q = createQuery(
			"SELECT id FROM cf_users WHERE email=:email",
			array('email'=>$email)
		);
		$q->execute();
		if (!$q->fetch())
		{
			return false;
		}
		return $q->at(0);
	}
	
	/**
		@return  ID of new user
	*/
	static public function register($login, $pass, $name, $lang, $email='')
	{
		if (self::findByLogin($login))
		{
			throw new Exception("User with login '$login' already exists");
		}
		
		$salt = substr(md5(microtime().rand()), 0, 8);
		
		execQuery(
			"INSERT INTO cf_users (login,password,salt,name,email,lang,registered)
			 VALUES (:login,:password,:salt,:name,:email,:lang,NOW())",
			array(
				'login'=>$login, 
				'password'=>self::generatePassword($pass,$salt), 
				'salt'=>$salt, 
				'name'=>$name, 
				'email'=>$email, 
				'lang'=>$lang
			)
		);
		
		global $db;
		return $db->lastInsertId();
	}
	
	static public function login($login, $pass, $remember=null)
	{
		$login = trim($login);
		$id = self::findByLogin($login);
		if (!$id)
		{
			throw new Exception("Login failed for user '$login'");
		}
		
		$user = new User($id);
		if (!$user->checkPassword($pass))
		{
			throw new Exception("Login failed for user '$login'");
		}
		
		$c = new Cookie('user');
		$c->setParam('id',$user->id());
		if ($remember)
		{
			$c->setExpirePeriod(5*355*24*60);
		}
		$c->set();
		
		self::updateLastLoginTime($user->id());
		
		return $user;
	}
	
	static public function getLoggedIn()
	{
		$c = Cookie::retrieve('user');
		if ($c) 
		{
			$id = $c->getParam('id');
			self::updateLastLoginTime($id);
			return new User($id);
		}
		return false;
	}
	
	/**
		find user by email and sets a random password
	*/
	static public function resetPwdByEmail($email)
	{
		$uid = self::findByEmail($email);
		if (!$uid) {
			return false;
		}
		$pwd = uniqid(rand());
		self::setPassword($uid, $pwd);
		return array(new User($uid), $pwd);
	}
	
	static public function setPassword($id, $pass)
	{
		execQuery(
			'UPDATE cf_users SET password=:pass WHERE id=:id', 
			array(
				'id'=>$id, 
				'pass'=>self::generatePassword(trim($pass),query2var('SELECT salt FROM cf_users WHERE id=:id',array('id'=>$id)))
			)
		);
	}


	static private function updateLastLoginTime($id)
	{
		execQuery("UPDATE cf_users SET last_login=NOW() WHERE id=$id");
	}	
	
	private function checkPassword($pass)
	{
		return self::generatePassword($pass,$this->salt) == $this->password;
	}
	
	static private function generatePassword($pass, $salt)
	{
		return md5($pass.$salt);
	}
	
	private $login = null;
	private $password = null;
	private $salt = null;
	private $name = null;
	private $email = null;
	private $lang = null;
	private $descr = null;
	private $registered = null;
	private $last_login = null;
	private $enabled = null;
};


?>